# monster.py
import pygame
from settings import *
import settings

# 使用向量进行精确的数学计算
vec = pygame.math.Vector2

class Monster(pygame.sprite.Sprite):
    def __init__(self, game, x, y):
        super().__init__()
        self.game = game
        # 定义野怪的大小和颜色
        self.size = 30
        self.color = (255, 0, 255)  # 紫色
        self.image = pygame.Surface((self.size, self.size))
        self.image.fill(self.color)
        self.rect = self.image.get_rect()
        self.rect.center = (x, y)
        self.pos = vec(x, y)
        self.vel = vec(0, 0)
        self.speed = MONSTER_SLOW_SPEED  # 野怪移动速度（降低三分之二）
        self.max_health = 50  # 野怪最大生命值
        self.health = self.max_health  # 当前生命值
        
        # 为野怪分配唯一ID
        self.id = id(self)
        
        # AI相关属性
        self.target = None  # 攻击目标（通常是玩家）
        self.attack_range = 40  # 攻击范围（像素）
        self.last_attack_time = 0  # 上次攻击时间
        self.attack_cooldown = 1000  # 攻击冷却时间（毫秒）
        self.attack_damage = 10  # 攻击力
        self.is_hostile = False  # 是否处于敌对状态
        
        # 寻路追踪相关属性
        self.target_path = []  # 目标路径
        self.path_index = 0  # 路径索引
        self.path_update_cooldown = 0  # 路径更新冷却时间
        self.path_update_interval = 2000  # 路径更新间隔增加到2秒（毫秒）

    def update(self):
        # 检查野怪是否死亡
        if self.health <= 0:
            self.die()
            return
            
        # 检查是否有目标
        self.check_for_target()
        
        # 更新移动逻辑 - 直接追踪玩家
        current_time = pygame.time.get_ticks()
        if self.target:
            # 使用寻路系统移动
            self.update_pathfinding_movement(current_time)
            
            # 检查是否可以攻击
            if current_time - self.last_attack_time >= self.attack_cooldown:
                self.attack()
        else:
            # 没有目标时，停止移动
            self.vel = vec(0, 0)
        
        # 根据速度更新位置
        self.pos += self.vel * self.game.dt
        self.rect.centerx = self.pos.x
        
        # 水平方向碰撞检测
        self.collide_with_obstacles('x')
        
        self.rect.centery = self.pos.y
        # 垂直方向碰撞检测
        self.collide_with_obstacles('y')
        
        # 防止野怪移出屏幕（与玩家相同的边界检查逻辑）
        if self.rect.left < 0:
            self.rect.left = 0
            self.pos.x = self.rect.centerx
        if self.rect.right > WIDTH:
            self.rect.right = WIDTH
            self.pos.x = self.rect.centerx
        if self.rect.top < 0:
            self.rect.top = 0
            self.pos.y = self.rect.centery
        if self.rect.bottom > HEIGHT:
            self.rect.bottom = HEIGHT
            self.pos.y = self.rect.centery
    
    def update_pathfinding_movement(self, current_time):
        """使用寻路系统更新野怪移动"""
        # 检查是否已经接近玩家（在攻击范围内）
        distance_to_target = (self.target.pos - self.pos).length()
        if distance_to_target <= self.attack_range:
            # 在攻击范围内，停止移动并准备攻击
            self.vel = vec(0, 0)
            self.target_path = []  # 清空路径
            self.path_index = 0
            return
        
        # 距离分级寻路策略：根据距离调整寻路频率
        if distance_to_target > 1000:  # 距离超过1000像素
            # 超远距离：每8秒更新一次路径，使用简单追踪
            path_update_interval = 8000
            use_simple_tracking = True
        elif distance_to_target > 500:  # 距离500-1000像素
            # 中距离：每5秒更新一次路径
            path_update_interval = 5000
            use_simple_tracking = False
        else:  # 距离小于500像素
            # 近距离：每2秒更新一次路径
            path_update_interval = 2000
            use_simple_tracking = False
        
        # 检查是否需要更新路径（使用分级策略）
        needs_path_update = (
            current_time - self.path_update_cooldown >= path_update_interval or
            not self.target_path or
            self.path_index >= len(self.target_path)
        )
        
        # 超远距离时，如果使用简单追踪，跳过寻路计算
        if use_simple_tracking:
            # 使用简单直线追踪，不进行寻路计算
            direction = (self.target.pos - self.pos).normalize()
            self.vel = direction * self.speed
            self.target_path = []  # 清空路径
            self.path_index = 0
            return
        
        if needs_path_update:
            # 更新路径
            self.update_path_to_target()
            self.path_update_cooldown = current_time
        
        # 如果有路径，沿着路径移动
        if self.target_path and self.path_index < len(self.target_path):
            target_pos = self.target_path[self.path_index]
            direction = (target_pos - self.pos).normalize()
            self.vel = direction * self.speed
            
            # 如果接近当前路径点，移动到下一个点
            if (self.pos - target_pos).length() < 10:  # 10像素容差
                self.path_index += 1
                
            # 如果已经到达路径终点但还没到玩家位置，使用简单追踪
            if self.path_index >= len(self.target_path) and distance_to_target > self.attack_range:
                direction = (self.target.pos - self.pos).normalize()
                self.vel = direction * self.speed
        else:
            # 没有路径时，使用简单追踪
            direction = (self.target.pos - self.pos).normalize()
            self.vel = direction * self.speed
    
    def update_path_to_target(self):
        """更新到目标的路径"""
        if not self.target or not hasattr(self.game, 'pathfinding_system'):
            return
        
        # 获取当前位置和目标位置的网格坐标
        start_grid_x = int(self.pos.x // GRID_SIZE)
        start_grid_y = int(self.pos.y // GRID_SIZE)
        target_grid_x = int(self.target.pos.x // GRID_SIZE)
        target_grid_y = int(self.target.pos.y // GRID_SIZE)
        
        # 确保坐标在网格范围内
        if not self.game.pathfinding_system.pathfinding_grid:
            return
            
        grid_width = self.game.pathfinding_system.pathfinding_grid.width
        grid_height = self.game.pathfinding_system.pathfinding_grid.height
        
        start_grid_x = max(0, min(start_grid_x, grid_width - 1))
        start_grid_y = max(0, min(start_grid_y, grid_height - 1))
        target_grid_x = max(0, min(target_grid_x, grid_width - 1))
        target_grid_y = max(0, min(target_grid_y, grid_height - 1))
        
        # 检查起点和终点是否相同或非常接近
        if abs(start_grid_x - target_grid_x) <= 1 and abs(start_grid_y - target_grid_y) <= 1:
            self.target_path = []
            self.path_index = 0
            return
        
        # 使用寻路系统查找路径
        path = self.game.pathfinding_system.find_path(
            self.pos.x, self.pos.y,  # 当前野怪位置（像素坐标）
            self.target.pos.x, self.target.pos.y  # 目标位置（像素坐标）
        )
        
        if path and len(path) > 1:
            # find_path返回的是像素坐标路径，直接使用
            self.target_path = [vec(x, y) for x, y in path]
            
            self.path_index = 0
            print(f"Monster {self.id} found path with {len(path)} points to target")
            
            # 检查路径是否有效（路径终点应该接近目标）
            last_path_point = self.target_path[-1]
            distance_to_target = (self.target.pos - last_path_point).length()
            if distance_to_target > settings.GRID_SIZE * 3:  # 放宽判断条件，3倍网格大小
                print(f"Monster {self.id}: 路径终点离目标较远 ({distance_to_target:.1f}像素)，但仍使用路径追踪")
                # 不清空路径，继续使用路径追踪
            else:
                print(f"Monster {self.id}: 路径终点接近目标 ({distance_to_target:.1f}像素)，路径有效")
        else:
            # 如果找不到路径，清空路径
            self.target_path = []
            self.path_index = 0
            print(f"Monster {self.id} could not find path to target")

    def collide_with_obstacles(self, dir):
        hits = pygame.sprite.spritecollide(self, self.game.obstacles, False)
        if hits:
            if dir == 'x':
                if self.vel.x > 0: # 向右移动
                    self.rect.right = hits[0].rect.left
                if self.vel.x < 0: # 向左移动
                    self.rect.left = hits[0].rect.right
                self.pos.x = self.rect.centerx
                self.vel.x = 0
            if dir == 'y':
                if self.vel.y > 0: # 向下移动
                    self.rect.bottom = hits[0].rect.top
                if self.vel.y < 0: # 向上移动
                    self.rect.top = hits[0].rect.bottom
                self.pos.y = self.rect.centery
                self.vel.y = 0

    def draw_health_bar(self, surface):
        """绘制血条"""
        if self.health < self.max_health:
            # 血条尺寸
            bar_length = self.size
            bar_height = 5
            # 血条位置（在怪物上方）
            bar_x = self.rect.x
            bar_y = self.rect.y - 10
            
            # 血条背景（红色）
            pygame.draw.rect(surface, (255, 0, 0), (bar_x, bar_y, bar_length, bar_height))
            
            # 当前血量（绿色）
            health_ratio = self.health / self.max_health
            pygame.draw.rect(surface, (0, 255, 0), (bar_x, bar_y, bar_length * health_ratio, bar_height))

    def check_for_target(self):
        """检查目标状态"""
        # 直接追踪玩家，不需要仇恨范围检查
        if self.target and not self.target.alive():
            # 目标已死亡，重置状态
            self.target = None
            self.is_hostile = False
            print("野怪：目标已死亡，停止追踪")
    
    def attack(self):
        """执行近战攻击"""
        if self.target and (self.target.pos - self.pos).length() <= self.attack_range:
            self.last_attack_time = pygame.time.get_ticks()
            # 对目标造成伤害
            if hasattr(self.target, 'health'):
                self.target.health -= self.attack_damage
                print(f"野怪攻击了玩家！造成{self.attack_damage}点伤害，玩家剩余血量：{self.target.health}")
                
                # 如果目标死亡
                if self.target.health <= 0:
                    self.target = None
                    self.is_hostile = False
                    print("野怪：目标已被击败！")
    
    def take_damage(self, damage, attacker=None):
        """受到伤害时的处理"""
        self.health -= damage
        print(f"野怪受到{damage}点伤害，剩余血量：{self.health}")
        
        # 如果被攻击，进入敌对状态并锁定攻击者
        if attacker:
            self.target = attacker
            self.is_hostile = True
            print("野怪：你竟敢攻击我！我要反击！")
        
        if self.health <= 0:
            self.die()
    
    def die(self):
        """死亡处理"""
        print("野怪被击败了！")
        self.kill()